package com.pro01.backend.service;

import com.pro01.backend.mapper.PointLogMapper;
import com.pro01.backend.mapper.UserPointMapper;
import com.pro01.backend.pojo.PageResult;
import com.pro01.backend.pojo.PointLog;
import com.pro01.backend.pojo.UserPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class PointService {

    @Autowired
    private PointLogMapper pointLogMapper;

    @Autowired
    private UserPointMapper userPointMapper;

    /**
     * 登录奖励逻辑，每天仅一次 +3
     */
    public void addLoginReward(Long userId) {
        int already = pointLogMapper.countTodayLoginPoints(userId);
        if (already > 0) return;

        int points = 3; // 登录奖励积分

        // 确保有积分总表
        if (userPointMapper.getByUserId(userId) == null) {
            userPointMapper.insertInitial(userId);
        }

        // 更新 user_points
        userPointMapper.addPoints(userId, points);

        // 添加日志
        PointLog log = new PointLog();
        log.setUserId(userId);
        log.setPoints(points);
        log.setChangeType("INCOME");
        log.setSource("LOGIN");
        log.setDescription("每日登录奖励");
        pointLogMapper.insertPointLog(log);
    }

    /**
     * 发帖积分 +5
     */
    public void addPostReward(Long userId) {
        int points = 5; // 发帖奖励分数

        // 确保有积分总表记录
        if (userPointMapper.getByUserId(userId) == null) {
            userPointMapper.insertInitial(userId);
        }

        // 积分总表更新
        userPointMapper.addPoints(userId, points);

        // 写入积分明细
        PointLog log = new PointLog();
        log.setUserId(userId);
        log.setPoints(points);
        log.setChangeType("INCOME");
        log.setSource("POST");
        log.setDescription("发帖奖励");
        pointLogMapper.insertPointLog(log);
    }

    /**
     * 上传种子积分 +10
     */
    public void addUploadReward(Long userId) {
        int points = 10; // 上传奖励积分

        // 确保总表存在
        if (userPointMapper.getByUserId(userId) == null) {
            userPointMapper.insertInitial(userId);
        }

        // 积分总表更新
        userPointMapper.addPoints(userId, points);

        // 积分日志写入
        PointLog log = new PointLog();
        log.setUserId(userId);
        log.setPoints(points);
        log.setChangeType("INCOME");
        log.setSource("UPLOAD");
        log.setDescription("上传种子奖励");
        pointLogMapper.insertPointLog(log);
    }

    /**
     * 获赞积分 +2
     */
    public void addLikeReward(Long userId) {
        int points = 2; // 被点赞奖励积分

        if (userPointMapper.getByUserId(userId) == null) {
            userPointMapper.insertInitial(userId);
        }

        userPointMapper.addPoints(userId, points);

        PointLog log = new PointLog();
        log.setUserId(userId);
        log.setPoints(points);
        log.setChangeType("INCOME");
        log.setSource("LIKE");
        log.setDescription("帖子被点赞奖励");
        pointLogMapper.insertPointLog(log);
    }

    /**
     * 查询用户总积分
     */
    public UserPoint getUserPoints(Long userId) {
        UserPoint point = userPointMapper.getByUserId(userId);
        if (point == null) {
            // 初始化记录（首次查看积分）
            userPointMapper.insertInitial(userId);
            point = userPointMapper.getByUserId(userId);
        }
        return point;
    }

    /**
     * 查询用户积分明细
     */
    public PageResult<PointLog> getUserPointLogs(Long userId, int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<PointLog> logs = pointLogMapper.getLogsByUser(userId, offset, pageSize);
        int total = pointLogMapper.countLogsByUser(userId);
        return new PageResult<>(total, logs);
    }

    /**
     * 用户积分排行榜
     */
    public Map<String, Object> getPointLeaderboardWithSelf(Long userId) {
        List<Map<String, Object>> topUsers = userPointMapper.getTop10ByPoints();
        Integer yourRank = userPointMapper.getUserRank(userId);
        Integer yourPoints = userPointMapper.getUserPoints(userId);

        Map<String, Object> result = new HashMap<>();
        result.put("rankList", topUsers);
        result.put("yourRank", yourRank != null ? yourRank : -1);         // -1 表示用户没有积分
        result.put("yourPoints", yourPoints != null ? yourPoints : 0);

        return result;
    }


    /**
     * 管理员查看所有用户积分
     */
    public PageResult<Map<String, Object>> getAllUserPoints(int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        List<Map<String, Object>> records = userPointMapper.selectAllUserPoints(offset, pageSize);
        int total = userPointMapper.countAllUserPoints();
        return new PageResult<>(total, records);
    }

    /**
     * 管理员奖励/扣除积分
     */
    public void adjustUserPoints(Long userId, int points, String changeType, String description) {
        if (!"INCOME".equals(changeType) && !"EXPENSE".equals(changeType)) {
            throw new RuntimeException("变动类型必须为 INCOME 或 EXPENSE");
        }

        if (points <= 0) {
            throw new RuntimeException("积分值必须为正数");
        }

        if (userPointMapper.getByUserId(userId) == null) {
            userPointMapper.insertInitial(userId);
        }

        // 更新积分总表
        if ("INCOME".equals(changeType)) {
            userPointMapper.addPoints(userId, points);
        } else {
            userPointMapper.subtractPoints(userId, points); // ✅ 你需要实现 subtractPoints 方法
        }

        // 添加日志
        PointLog log = new PointLog();
        log.setUserId(userId);
        log.setPoints(points);
        log.setChangeType(changeType);
        log.setSource("ADMIN_ADJUST");
        log.setDescription(description);
        pointLogMapper.insertPointLog(log);
    }

    /**
     * 获取用户积分的Map (显示用户信息的时候用)
     */
    public Map<String, Object> getUserPointsMap(Long userId) {
        UserPoint point = userPointMapper.getByUserId(userId);
        if (point == null) {
            return Map.of(
                    "currentPoints", 0,
                    "totalEarnedPoints", 0,
                    "totalUsedPoints", 0
            );
        }
        return Map.of(
                "currentPoints", point.getCurrentPoints(),
                "totalEarnedPoints", point.getTotalEarnedPoints(),
                "totalUsedPoints", point.getTotalUsedPoints()
        );
    }

}

